package com.wzh.oj.judge;

import cn.hutool.json.JSONUtil;
import com.wzh.oj.common.ErrorCode;
import com.wzh.oj.config.properties.CodeSandboxProperties;
import com.wzh.oj.exception.BusinessException;
import com.wzh.oj.judge.codesandbox.CodeSandbox;
import com.wzh.oj.judge.codesandbox.CodeSandboxFactory;
import com.wzh.oj.judge.codesandbox.CodesandboxProxy;
import com.wzh.oj.judge.codesandbox.model.ExecuteCodeRequest;
import com.wzh.oj.judge.codesandbox.model.ExecuteCodeResponse;
import com.wzh.oj.judge.codesandbox.model.JudgeContext;
import com.wzh.oj.judge.codesandbox.model.JudgeInfo;
import com.wzh.oj.model.dto.question.JudgeCase;
import com.wzh.oj.model.entity.Question;
import com.wzh.oj.model.entity.QuestionSubmit;
import com.wzh.oj.service.QuestionService;
import com.wzh.oj.service.QuestionSubmitService;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.stream.Collectors;

import static com.wzh.oj.model.enums.QuestionSubmitStatusEnum.RUNNING;
import static com.wzh.oj.model.enums.QuestionSubmitStatusEnum.WAITING;

/**
 * @author wzh
 */
@RequiredArgsConstructor
public class JudgeServiceImpl implements JudgeService {

    private final QuestionService questionService;

    private final QuestionSubmitService questionSubmitService;

    private final CodeSandboxProperties codeSandboxProperties;

    private final JudgeManage judgeManage;

    @Override
    public QuestionSubmit doJudge(long questionSubmitId) {
        QuestionSubmit submitRecord = questionSubmitService.getById(questionSubmitId);
        if (submitRecord == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "提交信息不存在");
        }
        Long questionId = submitRecord.getQuestionId();
        //获取题目信息
        Question quesInfo = questionService.getById(questionId);
        if (quesInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "题目不存在");
        }
        if (submitRecord.getStatus().equals(WAITING.getValue())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "题目正在判题中");
        }
//         更改提交状态为判题中
        submitRecord.setStatus(RUNNING.getValue());
        questionSubmitService.updateById(submitRecord);
//         调用沙箱，获取执行结果
        CodeSandbox codeSandbox = CodeSandboxFactory.getCodeSandbox(codeSandboxProperties.getType());
          codeSandbox=new CodesandboxProxy(codeSandbox);
        String judgeCaseStr = quesInfo.getJudgeCase();
        List<JudgeCase> judgeCases = JSONUtil.toList(judgeCaseStr, JudgeCase.class);
        List<String> inputs = judgeCases.stream().map(JudgeCase::getInput).collect(Collectors.toList());
        ExecuteCodeRequest executeCodeRequest=ExecuteCodeRequest.builder()
                .code(submitRecord.getCode())
                .language(submitRecord.getLanguage())
                .input(inputs).build();
        ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);

        List<String> outputList = executeCodeResponse.getOutputList();
        JudgeInfo judgeInfo = executeCodeResponse.getJudgeInfo();
        JudgeContext judgeContext = getJudgeContext(judgeInfo, outputList, inputs, quesInfo, judgeCases, submitRecord);
        JudgeInfo judgeInfos = judgeManage.doJudge(judgeContext);
//        修改数据库中的判题结果
        return null;
    }


    /**
     * 获取判题决策上下文对象
     * @param judgeInfo
     * @param outputList
     * @param inputList
     * @param question
     * @param judgeCaseList
     * @return JudgeContext
     */
    public JudgeContext getJudgeContext(JudgeInfo judgeInfo,List<String> outputList,List<String> inputList,Question question,List<JudgeCase> judgeCaseList,QuestionSubmit questionSubmit){
           return JudgeContext.builder()
                .judgeInfo(judgeInfo)
                .outputList(outputList)
                .question(question)
                .judgeCaseList(judgeCaseList).questionSubmit(questionSubmit)
                .inputList(inputList).build();
    }
}
